package com.github.pig.daemon.job.api;

import com.dangdang.ddframe.job.api.simple.SimpleJob;
import com.dangdang.ddframe.job.config.JobCoreConfiguration;
import com.dangdang.ddframe.job.config.simple.SimpleJobConfiguration;
import com.dangdang.ddframe.job.event.JobEventConfiguration;
import com.dangdang.ddframe.job.lite.config.LiteJobConfiguration;
import com.dangdang.ddframe.job.lite.spring.api.SpringJobScheduler;
import com.dangdang.ddframe.job.reg.zookeeper.ZookeeperRegistryCenter;

import javax.annotation.PostConstruct;
import javax.annotation.Resource;

/**
 * @author hankeke on 2018/8/8.
 * @version 1.0
 * @desc Simple类型作业
 *  需实现SimpleJob接口。该接口仅提供单一方法用于覆盖，此方法将定时执行。
 *  与Quartz原生接口相似，但提供了弹性扩缩容和分片等功能
 */
public abstract class SimpleJobApi implements SimpleJob {

    @Resource
    protected ZookeeperRegistryCenter regCenter;

    @Resource
    protected JobEventConfiguration jobEventConfiguration;

    /**
     * 作业启动时间的cron表达式
     *
     * @return
     */
    abstract protected String getCron();

    /**
     * 作业分片总数
     * 子类根据业务需要重写此方法
     * default 1
     * @return
     */
    protected int getShardingTotalCount() {
        return 1;
    }

    /**
     * 设置分片序列号和个性化参数对照表.
     * 子类根据需要重写此方法
     * <p>
     * <p>
     * 分片序列号和参数用等号分隔, 多个键值对用逗号分隔. 类似map. 分片序列号从0开始, 不可大于或等于作业分片总数. 如: 0=a,1=b,2=c
     * </p>
     *
     * @return
     */
    protected String getShardingItemParameters() {
        return "";
    }

    /**
     * 获取执行任务实例的Class
     *
     * @return example:DemoTask.Class;
     */
    abstract protected Class getJobClass();

    /**
     * @param jobClass
     * @param cron
     * @param shardingTotalCount
     * @param shardingItemParameters
     * @return
     */
    protected LiteJobConfiguration getLiteJobConfiguration(final Class<? extends SimpleJobApi> jobClass,
                                                           final String cron,
                                                           final int shardingTotalCount,
                                                           final String shardingItemParameters) {
        return LiteJobConfiguration
                .newBuilder(
                        new SimpleJobConfiguration(
                                JobCoreConfiguration.newBuilder(jobClass.getName(), cron, shardingTotalCount)
                                        .shardingItemParameters(shardingItemParameters).build(),
                                jobClass.getCanonicalName()))
                .overwrite(true).build();
    }

    @PostConstruct
    public void simpleJobScheduler() {
        new SpringJobScheduler(this,
                regCenter,
                getLiteJobConfiguration(this.getJobClass(), getCron(), getShardingTotalCount(), getShardingItemParameters()),
                jobEventConfiguration)
                .init();
    }


}
